package com.zdp.distributedemo.controller;

import com.zdp.distributedemo.lock.RedisLock;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.RedisStringCommands;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.RedisScript;
import org.springframework.data.redis.core.types.Expiration;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Arrays;
import java.util.List;
import java.util.UUID;

/**
 * @author sesshomaru
 * @date 2020/10/10 23:06
 * <p>
 * redis锁原理还是setnx命令 key为有意义的特定参数如订单id、库存id等
 * value为当前线程的一个随机数，解锁时需要判断redis中锁的value是否与当前线程的value一致
 * 通过这个解开属于当前线程的锁
 * 另外还要考虑一下锁续期的问题，就是锁解锁必须时在当前业务方法执行完成后才解锁
 */
@RestController
@Slf4j
public class RedisLockController {

    @Autowired
    private RedisTemplate redisTemplate;

    @RequestMapping("redisLock")
    public String redisLock() {
        log.info("我进入了方法！");
        RedisLock redisLock = new RedisLock(redisTemplate, "redisKey", 30);
        if (redisLock.getLock()) {
            try {
                log.info("我进入了锁！！");
                // 模拟执行业务方法
                Thread.sleep(15000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                redisLock.unLock();
            }
        }
        log.info("方法执行完成");
        return "方法执行完成";
    }
}
